home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / serial / serialwin32.py < prev    next >
Text File  |  2008-06-25  |  13KB  |  321 lines

  1. #! /usr/bin/python
  2. #Python Serial Port Extension for Win32, Linux, BSD, Jython
  3. #serial driver for win32
  4. #see __init__.py
  5. #
  6. #(C) 2001-2003 Chris Liechti <cliechti@gmx.net>
  7. # this is distributed under a free software license, see license.txt
  8.  
  9. import win32file  # The base COM port and file IO functions.
  10. import win32event # We use events and the WaitFor[Single|Multiple]Objects functions.
  11. import win32con   # constants.
  12. from serialutil import *
  13.  
  14. VERSION = "$Revision: 1.40 $".split()[1]     #extract CVS version
  15.  
  16. #from winbase.h. these should realy be in win32con
  17. MS_CTS_ON  = 16
  18. MS_DSR_ON  = 32
  19. MS_RING_ON = 64
  20. MS_RLSD_ON = 128
  21.  
  22. def device(portnum):
  23.     """Turn a port number into a device name"""
  24.     return 'COM%d' % (portnum+1) #numbers are transformed to a string
  25.  
  26. class Serial(SerialBase):
  27.     """Serial port implemenation for Win32. This implemenatation requires a 
  28.        win32all installation."""
  29.  
  30.     BAUDRATES = (50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,
  31.                  19200,38400,57600,115200)
  32.  
  33.     def open(self):
  34.         """Open port with current settings. This may throw a SerialException
  35.            if the port cannot be opened."""
  36.         if self._port is None:
  37.             raise SerialException("Port must be configured before it can be used.")
  38.         self.hComPort = None
  39.         try:
  40.             self.hComPort = win32file.CreateFile(self.makeDeviceName(self.portstr),
  41.                    win32con.GENERIC_READ | win32con.GENERIC_WRITE,
  42.                    0, # exclusive access
  43.                    None, # no security
  44.                    win32con.OPEN_EXISTING,
  45.                    win32con.FILE_FLAG_OVERLAPPED,
  46.                    None)
  47.         except Exception, msg:
  48.             self.hComPort = None    #'cause __del__ is called anyway
  49.             raise SerialException("could not open port %s: %s" % (self.portstr, msg))
  50.         # Setup a 4k buffer
  51.         win32file.SetupComm(self.hComPort, 4096, 4096)
  52.  
  53.         #Save original timeout values:
  54.         self._orgTimeouts = win32file.GetCommTimeouts(self.hComPort)
  55.  
  56.         self._rtsState = win32file.RTS_CONTROL_ENABLE
  57.         self._dtrState = win32file.DTR_CONTROL_ENABLE
  58.  
  59.         self._reconfigurePort()
  60.         
  61.         # Clear buffers:
  62.         # Remove anything that was there
  63.         win32file.PurgeComm(self.hComPort,
  64.                             win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT |
  65.                             win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
  66.  
  67.         self._overlappedRead = win32file.OVERLAPPED()
  68.         self._overlappedRead.hEvent = win32event.CreateEvent(None, 1, 0, None)
  69.         self._overlappedWrite = win32file.OVERLAPPED()
  70.         #~ self._overlappedWrite.hEvent = win32event.CreateEvent(None, 1, 0, None)
  71.         self._overlappedWrite.hEvent = win32event.CreateEvent(None, 0, 0, None)
  72.         self._isOpen = True
  73.  
  74.     def _reconfigurePort(self):
  75.         """Set commuication parameters on opened port."""
  76.         if not self.hComPort:
  77.             raise SerialException("Can only operate on a valid port handle")
  78.         
  79.         #Set Windows timeout values
  80.         #timeouts is a tuple with the following items:
  81.         #(ReadIntervalTimeout,ReadTotalTimeoutMultiplier,
  82.         # ReadTotalTimeoutConstant,WriteTotalTimeoutMultiplier,
  83.         # WriteTotalTimeoutConstant)
  84.         if self._timeout is None:
  85.             timeouts = (0, 0, 0, 0, 0)
  86.         elif self._timeout == 0:
  87.             timeouts = (win32con.MAXDWORD, 0, 0, 0, 0)
  88.         else:
  89.             timeouts = (0, 0, int(self._timeout*1000), 0, 0)
  90.         if self._writeTimeout is None:
  91.             pass
  92.         elif self._writeTimeout == 0:
  93.             timeouts = timeouts[:-2] + (0, win32con.MAXDWORD)
  94.         else:
  95.             timeouts = timeouts[:-2] + (0, int(self._writeTimeout*1000))
  96.         win32file.SetCommTimeouts(self.hComPort, timeouts)
  97.  
  98.         win32file.SetCommMask(self.hComPort, win32file.EV_ERR)
  99.  
  100.         # Setup the connection info.
  101.         # Get state and modify it:
  102.         comDCB = win32file.GetCommState(self.hComPort)
  103.         comDCB.BaudRate = self._baudrate
  104.  
  105.         if self._bytesize == FIVEBITS:
  106.             comDCB.ByteSize     = 5
  107.         elif self._bytesize == SIXBITS:
  108.             comDCB.ByteSize     = 6
  109.         elif self._bytesize == SEVENBITS:
  110.             comDCB.ByteSize     = 7
  111.         elif self._bytesize == EIGHTBITS:
  112.             comDCB.ByteSize     = 8
  113.         else:
  114.             raise ValueError("Unsupported number of data bits: %r" % self._bytesize)
  115.  
  116.         if self._parity == PARITY_NONE:
  117.             comDCB.Parity       = win32file.NOPARITY
  118.             comDCB.fParity      = 0 # Dis/Enable Parity Check
  119.         elif self._parity == PARITY_EVEN:
  120.             comDCB.Parity       = win32file.EVENPARITY
  121.             comDCB.fParity      = 1 # Dis/Enable Parity Check
  122.         elif self._parity == PARITY_ODD:
  123.             comDCB.Parity       = win32file.ODDPARITY
  124.             comDCB.fParity      = 1 # Dis/Enable Parity Check
  125.         else:
  126.             raise ValueError("Unsupported parity mode: %r" % self._parity)
  127.  
  128.         if self._stopbits == STOPBITS_ONE:
  129.             comDCB.StopBits     = win32file.ONESTOPBIT
  130.         elif self._stopbits == STOPBITS_TWO:
  131.             comDCB.StopBits     = win32file.TWOSTOPBITS
  132.         else:
  133.             raise ValueError("Unsupported number of stop bits: %r" % self._stopbits)
  134.             
  135.         comDCB.fBinary          = 1 # Enable Binary Transmission
  136.         # Char. w/ Parity-Err are replaced with 0xff (if fErrorChar is set to TRUE)
  137.         if self._rtscts:
  138.             comDCB.fRtsControl  = win32file.RTS_CONTROL_HANDSHAKE
  139.         else:
  140.             comDCB.fRtsControl  = self._rtsState
  141.         if self._dsrdtr:
  142.             comDCB.fDtrControl  = win32file.DTR_CONTROL_HANDSHAKE
  143.         else:
  144.             comDCB.fDtrControl  = self._dtrState
  145.         comDCB.fOutxCtsFlow     = self._rtscts
  146.         comDCB.fOutxDsrFlow     = self._dsrdtr
  147.         comDCB.fOutX            = self._xonxoff
  148.         comDCB.fInX             = self._xonxoff
  149.         comDCB.fNull            = 0
  150.         comDCB.fErrorChar       = 0
  151.         comDCB.fAbortOnError    = 0
  152.         comDCB.XonChar          = XON
  153.         comDCB.XoffChar         = XOFF
  154.  
  155.         try:
  156.             win32file.SetCommState(self.hComPort, comDCB)
  157.         except win32file.error, e:
  158.             raise ValueError("Cannot configure port, some setting was wrong. Original message: %s" % e)
  159.  
  160.     #~ def __del__(self):
  161.         #~ self.close()
  162.  
  163.     def close(self):
  164.         """Close port"""
  165.         if self._isOpen:
  166.             if self.hComPort:
  167.                 try:
  168.                     # Restore original timeout values:
  169.                     win32file.SetCommTimeouts(self.hComPort, self._orgTimeouts)
  170.                 except win32file.error:
  171.                     # ignore errors. can happen for unplugged USB serial devices
  172.                     pass
  173.                 # Close COM-Port:
  174.                 win32file.CloseHandle(self.hComPort)
  175.                 win32file.CloseHandle(self._overlappedRead.hEvent)
  176.                 win32file.CloseHandle(self._overlappedWrite.hEvent)
  177.                 self.hComPort = None
  178.             self._isOpen = False
  179.  
  180.     def makeDeviceName(self, port):
  181.         # the "\\.\COMx" format is required for devices other than COM1-COM8
  182.         # not all versions of windows seem to support this properly
  183.         # so that the first few ports are used with the DOS device name
  184.         if port.upper().startswith('COM') and int(port[3:]) <= 8:
  185.             return port
  186.         return '\\\\.\\' + port
  187.  
  188.     #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  189.     
  190.     def inWaiting(self):
  191.         """Return the number of characters currently in the input buffer."""
  192.         flags, comstat = win32file.ClearCommError(self.hComPort)
  193.         return comstat.cbInQue
  194.  
  195.     def read(self, size=1):
  196.         """Read size bytes from the serial port. If a timeout is set it may
  197.            return less characters as requested. With no timeout it will block
  198.            until the requested number of bytes is read."""
  199.         if not self.hComPort: raise portNotOpenError
  200.         if size > 0:
  201.             win32event.ResetEvent(self._overlappedRead.hEvent)
  202.             flags, comstat = win32file.ClearCommError(self.hComPort)
  203.             if self.timeout == 0:
  204.                 n = min(comstat.cbInQue, size)
  205.                 if n > 0:
  206.                     rc, buf = win32file.ReadFile(self.hComPort, win32file.AllocateReadBuffer(n), self._overlappedRead)
  207.                     win32event.WaitForSingleObject(self._overlappedRead.hEvent, win32event.INFINITE)
  208.                     read = str(buf)
  209.                 else:
  210.                     read = ''
  211.             else:
  212.                 rc, buf = win32file.ReadFile(self.hComPort, win32file.AllocateReadBuffer(size), self._overlappedRead)
  213.                 n = win32file.GetOverlappedResult(self.hComPort, self._overlappedRead, 1)
  214.                 read = str(buf[:n])
  215.         else:
  216.             read = ''
  217.         return read
  218.  
  219.     def write(self, data):
  220.         """Output the given string over the serial port."""
  221.         if not self.hComPort: raise portNotOpenError
  222.         if not isinstance(data, str):
  223.             raise TypeError('expected str, got %s' % type(data))
  224.         #print repr(s),
  225.         if data:
  226.             #~ win32event.ResetEvent(self._overlappedWrite.hEvent)
  227.             err, n = win32file.WriteFile(self.hComPort, data, self._overlappedWrite)
  228.             if err: #will be ERROR_IO_PENDING:
  229.                 # Wait for the write to complete.
  230.                 #~ win32event.WaitForSingleObject(self._overlappedWrite.hEvent, win32event.INFINITE)
  231.                 n = win32file.GetOverlappedResult(self.hComPort, self._overlappedWrite, 1)
  232.                 if n != len(data):
  233.                     raise writeTimeoutError
  234.                 
  235.  
  236.     def flushInput(self):
  237.         """Clear input buffer, discarding all that is in the buffer."""
  238.         if not self.hComPort: raise portNotOpenError
  239.         win32file.PurgeComm(self.hComPort, win32file.PURGE_RXCLEAR | win32file.PURGE_RXABORT)
  240.  
  241.     def flushOutput(self):
  242.         """Clear output buffer, aborting the current output and
  243.         discarding all that is in the buffer."""
  244.         if not self.hComPort: raise portNotOpenError
  245.         win32file.PurgeComm(self.hComPort, win32file.PURGE_TXCLEAR | win32file.PURGE_TXABORT)
  246.  
  247.     def sendBreak(self, duration=0.25):
  248.         """Send break condition."""
  249.         if not self.hComPort: raise portNotOpenError
  250.         import time
  251.         win32file.SetCommBreak(self.hComPort)
  252.         time.sleep(duration)
  253.         win32file.ClearCommBreak(self.hComPort)
  254.  
  255.     def setRTS(self, level=1):
  256.         """Set terminal status line: Request To Send"""
  257.         if not self.hComPort: raise portNotOpenError
  258.         if level:
  259.             self._rtsState = win32file.RTS_CONTROL_ENABLE
  260.             win32file.EscapeCommFunction(self.hComPort, win32file.SETRTS)
  261.         else:
  262.             self._rtsState = win32file.RTS_CONTROL_DISABLE
  263.             win32file.EscapeCommFunction(self.hComPort, win32file.CLRRTS)
  264.  
  265.     def setDTR(self, level=1):
  266.         """Set terminal status line: Data Terminal Ready"""
  267.         if not self.hComPort: raise portNotOpenError
  268.         if level:
  269.             self._dtrState = win32file.DTR_CONTROL_ENABLE
  270.             win32file.EscapeCommFunction(self.hComPort, win32file.SETDTR)
  271.         else:
  272.             self._dtrState = win32file.DTR_CONTROL_DISABLE
  273.             win32file.EscapeCommFunction(self.hComPort, win32file.CLRDTR)
  274.  
  275.     def getCTS(self):
  276.         """Read terminal status line: Clear To Send"""
  277.         if not self.hComPort: raise portNotOpenError
  278.         return MS_CTS_ON & win32file.GetCommModemStatus(self.hComPort) != 0
  279.  
  280.     def getDSR(self):
  281.         """Read terminal status line: Data Set Ready"""
  282.         if not self.hComPort: raise portNotOpenError
  283.         return MS_DSR_ON & win32file.GetCommModemStatus(self.hComPort) != 0
  284.  
  285.     def getRI(self):
  286.         """Read terminal status line: Ring Indicator"""
  287.         if not self.hComPort: raise portNotOpenError
  288.         return MS_RING_ON & win32file.GetCommModemStatus(self.hComPort) != 0
  289.  
  290.     def getCD(self):
  291.         """Read terminal status line: Carrier Detect"""
  292.         if not self.hComPort: raise portNotOpenError
  293.         return MS_RLSD_ON & win32file.GetCommModemStatus(self.hComPort) != 0
  294.  
  295.     # - - platform specific - - - -
  296.  
  297.     def setXON(self, level=True):
  298.         """Platform specific - set flow state."""
  299.         if not self.hComPort: raise portNotOpenError
  300.         if level:
  301.             win32file.EscapeCommFunction(self.hComPort, win32file.SETXON)
  302.         else:
  303.             win32file.EscapeCommFunction(self.hComPort, win32file.SETXOFF)
  304.  
  305. #Nur Testfunktion!!
  306. if __name__ == '__main__':
  307.     s = Serial(0)
  308.     print s
  309.     
  310.     s = Serial()
  311.     print s
  312.     
  313.     
  314.     s.baudrate = 19200
  315.     s.databits = 7
  316.     s.close()
  317.     s.port = 0
  318.     s.open()
  319.     print s
  320.  
  321.